//绘制地图功能

#include"graph.h"
#include"SchoolBus.h"

/*函数作图（绘制道路）思路：直线可以看作由无穷多个点组成，而每个点的大小可以看作无穷小
因此设置一个参数eps（为graph.h中的DotSize），既表示点的半径，又表示每个点直接的距离
这样通过循环，无穷多个点能够粘连在一起，形成一个直线
*/



void Download() {         //下载相应图片
	loadimage(&BlackDot, "BlackDot.jpg", DotSize, DotSize);    //黑点   
	loadimage(&CrossRoadImage, "CrossRoadImage.jpg",CrossSize, CrossSize);          //十字路口
	loadimage(&RedDot, "RedDot.jpg", DotSize, DotSize);    //红点
	loadimage(&OrangeDot, "OrangeDot.jpg", DotSize, DotSize);    //橙色点
	loadimage(&StationImage, "StationImage", StationSize, StationSize);          //公交站点
	loadimage(&GreenDot, "GreenDot.jpg", DotSize, DotSize);    //绿点
	return;
}

//直线道路作图
void DrawStraight(Straight a,IMAGE color) {
	Download();
	for (double i = a.Edge1->Getx(); i <= a.Edge2->Getx(); i += DotSize) {
		putimage(i, a.slope * i + a.intercept, &color);
	}
	return;
}
	
//曲线道路作图
void DrawCurve(Curve a, IMAGE color) {
	Download();
	for (double i = a.Edge1->Getx(); i <= a.Edge2->Getx(); i += DotSize) {
		putimage(i, a.formula(i), &color);
	}
	return;
}

//直线道路作图,实际程序需要传入Line*对象，故需要基于上述程序修改函数内容

void DrawStraight(Line* a, IMAGE color) {
	Download();
	double x1 = a->Edge1->Getx();
	double x2 = a->Edge2->Getx();
	double y1 = a->Edge1->Gety();
	double y2 = a->Edge2->Gety();
	double k = (y2 - y1) / (x2 - x1);
	double b = y1 - k * x1;   //求出直线解析式
	if (a->Edge1->Getx() < a->Edge2->Getx()) {
		for (double i = a->Edge1->Getx(); i <= a->Edge2->Getx(); i += DotSize / 100) {
			putimage(i, k * i + b, &color);
		}
	}
	else {
		for (double i = a->Edge2->Getx(); i <= a->Edge1->Getx(); i += DotSize / 100) {
			putimage(i, k * i + b, &color);
		}
	}
	int xz = (x1 + x2) / 2;
	int yz = (y1 + y2) / 2;
	string name = a->Getname();
	LPCTSTR str = name.c_str();
	settextcolor(RGB(46,177,166));
	settextstyle(12, 0, "宋体");
	outtextxy(xz,yz, str);
	return;
}


//把点、线从库中导入到地图上
void DrawMap() {
	Download();
	for (int i = 0; i < LineKu.size(); i++) {     //绘线
		if (LineKu[i]->Gettype() == 1) {        //绘制直线
			DrawStraight(LineKu[i], BlackDot);
		}
		else if (LineKu[i]->Gettype() == 2) {        //绘制曲线
			//曲线扩展功能完成后补充代码，需要借助解析器功能将string转换为function
		}
	}
	for (int i = 0; i < DotKu.size(); i++) {    //绘点
		if (DotKu[i]->Gettype() == 1) {      //绘制普通点
			putimage(DotKu[i]->Getx(), DotKu[i]->Gety(), &BlackDot);
		}
		else if (DotKu[i]->Gettype() == 2) {      //绘制景点
			string pname = "./";
			pname.append(DotKu[i]->Getname());
			pname.append(".png");
			IMAGE placeP;
			loadimage(&placeP, pname.c_str(), ScenerySize, ScenerySize);
			int imax = DotKu[i]->Getx(); imax = imax - 8;
			int imay = DotKu[i]->Gety(); imay = imay - 6;
			putimage(imax, imay, &placeP);
		}
		else if (DotKu[i]->Gettype() == 3) {      //绘制十字路口
			putimage(DotKu[i]->Getx(), DotKu[i]->Gety(), &CrossRoadImage);
		}
		else if (DotKu[i]->Gettype() == 4) {      //绘制公交站点
			putimage(DotKu[i]->Getx(), DotKu[i]->Gety(), &StationImage);
		}
		settextcolor(RGB(230, 83, 100));
		settextstyle(12, 0, "宋体");
		char TID[100];
		sprintf_s(TID, "%d", DotKu[i]->GetID());
		outtextxy(DotKu[i]->Getx(), DotKu[i]->Gety(), TID);
	}
	return;
}

//画出一条路径
void DrawPath(vector<Dot*>Path, IMAGE color) {     //第一个参数传路径，第二个参数传颜色，具体见本文件第10行语句
	Download();
	for (int j = 0; j < Path.size(); j++) {
		putimage(Path[j]->Getx(), Path[j]->Gety(), &color);
	}      //绘点
	for (int j = 0; j < Path.size() - 1; j++) {
		for (int r = 0; r < LineKu.size(); r++) {
			if (LineKu[r]->GetEdge1ID() == DotSearch[Path[j]] && LineKu[r]->GetEdge2ID() == DotSearch[Path[j + 1]] || LineKu[r]->GetEdge2ID() == DotSearch[Path[j]] && LineKu[r]->GetEdge1ID() == DotSearch[Path[j + 1]]) {   //找到对应的线
				if (LineKu[r]->Getlength() - sqrt(pow(Path[j + 1]->Gety() - Path[j]->Gety(), 2) + pow(Path[j + 1]->Getx() - Path[j]->Getx(), 2)) <= eps) {   //鉴定为直线
					DrawStraight(LineKu[r], color);
				}
				else {
					//曲线扩展功能完成后补充代码
				}
				break;
			}
		}
	}      //绘线
	return;
}


//画出一条路径
void DrawPath(vector<Dot*>Path, bool isshort) {     //第一个参数传路径，第二个参数传颜色，具体见本文件第10行语句
	IMAGE color;
	if (isshort) {
		color = RedDot; //最短用红色
	}
	else {
		color = OrangeDot;
	}
	Download();

	for (int j = 0; j < Path.size(); j++) {
		putimage(Path[j]->Getx(), Path[j]->Gety(), &color);
	}      //绘点
	for (int j = 0; j < Path.size() - 1; j++) {
	for (int r = 0; r < LineKu.size(); r++) {
		if (LineKu[r]->GetEdge1ID() == Path[j]->GetID() && LineKu[r]->GetEdge2ID() == Path[j + 1]->GetID()) {   //找到对应的线
			DrawStraight(LineKu[r], color);
		}
		else if (LineKu[r]->GetEdge2ID() == Path[j]->GetID() && LineKu[r]->GetEdge1ID() == Path[j + 1]->GetID()) {
			DrawStraight(LineKu[r], color);
		}
	}
}      //绘线
}

//路径查询系统：把查询到的路径显示地图上（最短路径用红色显示，非最短路径用橙色显示）
void DrawRoots(Dot* source, Dot* target) {
	vector<double> pathLengths;
	vector<vector<Dot*>> Roots = FindRoot(source, target, pathLengths);  //获得路径
	for (int i = 0; i < Roots.size(); i++) {
		if (pathLengths[i] - pathLengths[0] <= eps) {      //是最短路径，标红
			DrawPath(Roots[i], RedDot);
		}
		else {      //不是最短路径，标橙
			DrawPath(Roots[i], OrangeDot);
		}
	}
	return;
}

//绘制校车的通行路线
void DrawSchoolBusRoot(SchoolBus a) {
	vector<Dot*>p = a.Station;
	DrawPath(p, GreenDot);
	return;
}

//绘制校车导航的路线
void DrawBusNavigation(Dot* source, Dot* target) {
	double walkinglength1; double Buslength; double walkinglength2; vector<Dot*> path1; vector<Dot*> path2; vector<Dot*> path3;
	BusNavigation(source, target, walkinglength1, Buslength, walkinglength2, path1, path2, path3);
	DrawPath(path1,RedDot);
	DrawPath(path2, GreenDot);
	DrawPath(path3, RedDot);
	return;
}